﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Data.MainServiceData;
using CPPEI.Coolzon.Server.CacheData;
using CPPEI.Coolzon.Service.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.Server.ServiceImplement.CreateDomain
{
    /// <summary>
    /// 单一控制域模式的创建策略,
    /// 单一模式只允许服务器上存在一个控制域
    /// 如果域已存在，但是域里的方案和要创建的方案不一致，那么通知在域里的用户切换方案
    /// </summary>
    class SingletonModeCreateDomainStrategy
    {
        public RespCreateDomainData CreateDomain(Request request, ReqCreateDomainData requestData, CacheData.Client client)
        {
            RespCreateDomainData result = new RespCreateDomainData();

            #region 检查域是否存在
            CacheData.ControlDomain existDomain = null;
            string solutionName = requestData.SolutionName;
            CacheData.ControlDomain[] domainList = ServerData.Instance.GetDomainList();
            for (int index = 0; index < domainList.Length; index++)
            {
                CacheData.ControlDomain domain = domainList[index];
                if (domain != null)
                {
                    // 发现已存在的控制域
                    existDomain = domain;
                    break;
                }
            }
            #endregion

            if (existDomain == null)
            {
                string domainId = string.Format("domain-{0}-{1}", requestData.SolutionName, request.Header.UserIdentity);

                existDomain = new CacheData.ControlDomain()
                    {
                        Id = ServerData.UniqueDomainId,
                        SolutionCaption = requestData.SolutionCaption,
                        SolutionName = requestData.SolutionName,
                        Caption = requestData.DomainCaption,
                        CreatorAccount = client.UserAccount,
                        CreatorName = client.UserAccount
                    };

                if (ServerData.Instance.CreateDomain(existDomain))
                {
                    #region // 创建成功

                    #region // 将用户分配到控制域中
                    existDomain.AddClient(client);
                    client.State = ClientState.InDomain;
                    #endregion

                    #region // 判断是否是控制端
                    if (client.AppType.ToUpper() == "CONSOLEAPP")
                    {
                        // 设置为操作员
                        existDomain.SetOperator(client);
                    }
                    #endregion

                    result.IsSuccess = true;
                    result.Message = "创建成功";
                    result.IsNewDomain = true;
                    result.DomainId = existDomain.Id;
                    result.DomainCaption = existDomain.Caption;
                    result.OperatorIdentity = existDomain.OperatorIdentity;
                    Logger.InfoToTag("MainService", string.Format("用户{0}创建域{1}成功,DomainId:{2},Solution:{3}！",
                        request.Header.UserIdentity,
                        requestData.DomainCaption,
                        existDomain.Id,
                        requestData.SolutionName));

                    // 通知其他用户加入控制域
                    DomainUtil.NotifyDisplayClientEnter(request, existDomain);
                    #endregion
                }
                else
                {
                    // 创建失败
                    result.IsSuccess = false;
                    result.Message = "创建域失败";
                }
            }
            else
            {
                // 判断是否是控制端
                if (string.Equals(client.AppType, "CONSOLEAPP", StringComparison.CurrentCultureIgnoreCase))
                {
                    #region 控制端
                    Client existConsoleClient = existDomain.GetConsoleClient();
                    if (existConsoleClient == null)
                    {
                        // 将用户分配到控制域中
                        existDomain.AddClient(client);
                        client.State = ClientState.InDomain;

                        // 判断域里是否有操作员
                        if (!existDomain.ValidateOperator())
                        {
                            // 设置为操作员
                            existDomain.SetOperator(client);
                        }

                        result.IsSuccess = true;
                        result.Message = "创建成功，域已存在不需要创建";

                        if (string.Equals(existDomain.SolutionName, requestData.SolutionName))
                        {
                            // 需要创建的方案和域里的方案一致
                            if (string.IsNullOrEmpty(existDomain.ViewStateToken))
                            {
                                // 域里没有viewstate视为新的域
                                result.IsNewDomain = true;
                                Logger.WarningToTag("MainService", string.Format("用户{0}创建{1}成功，域:{2}已存在,但是视图状态无效视为新的域！",
                                    request.Header.UserIdentity,
                                    requestData.DomainCaption,
                                    existDomain.Id));
                            }
                            else
                            {
                                result.IsNewDomain = false;
                                Logger.InfoToTag("MainService", string.Format("用户{0}创建{1}成功，域:{2}已存在！",
                                    request.Header.UserIdentity,
                                    requestData.DomainCaption,
                                    existDomain.Id));
                            }
                        }
                        else
                        {
                            // 需要创建的方案和域里的方案不一致
                            existDomain.ResetViewState();
                            existDomain.SolutionName = requestData.SolutionName;

                            DomainUtil.NotifyOtherClientSwitchSolution(request, existDomain, client, requestData.SolutionName);

                            result.IsNewDomain = true;
                            Logger.InfoToTag("MainService", string.Format("用户{0}创建{1}成功，域:{2}已存在，并通知其他人切换方案:{3}！域中不存在控制端",
                                request.Header.UserIdentity,
                                requestData.DomainCaption,
                                existDomain.Id,
                                requestData.SolutionName));
                        }
                    }
                    else
                    {
                        if (CacheData.CacheDataUtil.RemoveClientIfTimeoutButReserveDomain(CacheData.ServerData.Instance, existConsoleClient))
                        {
                            // 存在控制端，而且控制端已经超时未连接了
                            // 将用户分配到控制域中
                            existDomain.AddClient(client);
                            client.State = ClientState.InDomain;

                            // 判断域里是否有操作员
                            if (!existDomain.ValidateOperator())
                            {
                                // 设置为操作员
                                existDomain.SetOperator(client);
                            }

                            result.IsSuccess = true;
                            result.Message = "创建成功，域已存在不需要创建";

                            if (string.Equals(existDomain.SolutionName, requestData.SolutionName))
                            {
                                // 需要创建的方案和域里的方案一致
                                result.IsNewDomain = false;

                                Logger.InfoToTag("MainService", string.Format("用户{0}创建{1}成功，域:{2}已存在！",
                                    request.Header.UserIdentity,
                                    requestData.DomainCaption,
                                    existDomain.Id));
                            }
                            else
                            {
                                // 需要创建的方案和域里的方案不一致
                                existDomain.ResetViewState();
                                existDomain.SolutionName = requestData.SolutionName;

                                DomainUtil.NotifyOtherClientSwitchSolution(request, existDomain, client, requestData.SolutionName);

                                result.IsNewDomain = true;
                                Logger.InfoToTag("MainService", string.Format("用户{0}创建{1}成功，域:{2}已存在，并通知其他人切换方案:{3}！",
                                    request.Header.UserIdentity,
                                    requestData.DomainCaption,
                                    existDomain.Id,
                                    requestData.SolutionName));
                            }
                        }
                        else
                        {
                            result.IsSuccess = false;
                            result.Message = "创建失败，域已存在，且已存在控制端";
                            result.IsNewDomain = false;

                            Logger.ErrorToTag("MainService", string.Format("用户{0}创建{1}失败，域已存在，且已存在控制端,DomainId:{2}！", request.Header.UserIdentity, requestData.DomainCaption, existDomain.Id));
                        }
                    }
                    #endregion
                }
                else
                {
                    // 非控制端直接加入进去
                    existDomain.AddClient(client);
                    client.State = ClientState.InDomain;

                    result.IsSuccess = true;
                    result.Message = "创建成功，域已存在不需要创建";
                    result.IsNewDomain = false;
                }

                result.DomainId = existDomain.Id;
                result.DomainCaption = existDomain.Caption;
                result.OperatorIdentity = existDomain.OperatorIdentity;
            }

            return result;
        }
    }
}
